<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Getting started with Reactive</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/getting-started-reactive" />
  <meta property="og:title" content="Quarkus - Getting started with Reactive" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/getting-started-reactive">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Getting started with Reactive</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#solutions">Solutions</a></li>
<li><a href="#the-multiple-reactive-facets-of-quarkus">The multiple reactive facets of Quarkus</a></li>
<li><a href="#mutiny">Mutiny - A reactive programming library</a></li>
<li><a href="#bootstrapping-the-project">Bootstrapping the project</a>
<ul class="sectlevel2">
<li><a href="#reactive-jax-rs-resources">Reactive JAX-RS resources</a></li>
</ul>
</li>
<li><a href="#handling-streams">Handling streams</a></li>
<li><a href="#using-reactive-apis">Using Reactive APIs</a>
<ul class="sectlevel2">
<li><a href="#using-quarkus-reactive-apis">Using Quarkus reactive APIs</a></li>
<li><a href="#using-vert-x-clients">Using Vert.x clients</a></li>
<li><a href="#using-rxjava-or-reactor-apis">Using RxJava or Reactor APIs</a></li>
<li><a href="#using-completionstages-or-publisher-api">Using CompletionStages or Publisher API</a></li>
</ul>
</li>
<li><a href="#whats-next">What&#8217;s next?</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Learn how to create a reactive application with Quarkus and explore the different reactive features offered by Quarkus.
This guide covers:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A quick glance at the Quarkus engine and how it enables reactive</p>
</li>
<li>
<p>A brief introduction to Mutiny - the reactive programming library used by Quarkus</p>
</li>
<li>
<p>Bootstrapping a reactive application</p>
</li>
<li>
<p>Creating a reactive JAX-RS endpoint (asynchronous, streams&#8230;&#8203;)</p>
</li>
<li>
<p>Using reactive database access</p>
</li>
<li>
<p>Interacting with other reactive APIs</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="prerequisites"><a class="anchor" href="#prerequisites"></a>Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To complete this guide, you need:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>less than 15 minutes</p>
</li>
<li>
<p>an IDE</p>
</li>
<li>
<p>JDK 8 or 11+ installed with <code>JAVA_HOME</code> configured appropriately</p>
</li>
<li>
<p>Apache Maven 3.6.2+</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="solutions"><a class="anchor" href="#solutions"></a>Solutions</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We recommend that you follow the instructions from <a href="#bootstrapping-the-project">Boostrapping project</a> and onwards to create the application step by step.</p>
</div>
<div class="paragraph">
<p>However, you can go right to the completed example.</p>
</div>
<div class="paragraph">
<p>Download an <a href="https://github.com/quarkusio/quarkus-quickstarts/archive/master.zip">archive</a> or clone the git repository:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">git clone https://github.com/quarkusio/quarkus-quickstarts.git</code></pre>
</div>
</div>
<div class="paragraph">
<p>The solutions are located in the <code>getting-started-reactive</code> and <code>getting-started-reactive-crud</code> directories.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="the-multiple-reactive-facets-of-quarkus"><a class="anchor" href="#the-multiple-reactive-facets-of-quarkus"></a>The multiple reactive facets of Quarkus</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus is reactive.
If you look under the hood, you will find a reactive engine powering your Quarkus application.
This engine is Eclipse Vert.x (<a href="https://vertx.io" class="bare">https://vertx.io</a>).
Every IO interaction passes through the non-blocking and reactive Vert.x engine.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="/guides/images/quarkus-reactive-stack.png" alt="Quarkus is based on a reactive engine" width="50%"></span></p>
</div>
<div class="paragraph">
<p>Let&#8217;s take 2 examples to explain how it works.
Imagine an incoming HTTP request.
The (Vert.x) HTTP server receives the request and then routes it to the application.
If the request targets a JAX-RS resource, the routing layer invokes the resource method in a worker thread and writes the response when the data is available.
So far, nothing new or outstanding.
The following picture depicts this behavior.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="/guides/images/http-blocking-sequence.png" alt="Behavior when using the imperative routes" width="50%"></span></p>
</div>
<div class="paragraph">
<p>But if the HTTP request targets a reactive (non-blocking) route, the routing layer invokes the route on the IO thread giving lots of benefits such as higher concurrency and performance:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="/guides/images/http-reactive-sequence.png" alt="Behavior when using the reactive routes" width="50%"></span></p>
</div>
<div class="paragraph">
<p>As a consequence, many Quarkus components are designed with reactive in mind, such as database access (PostgreSQL, MySQL, Mongo, etc.), application services (mail, template engine, etc.), messaging (Kafka, AMQP, etc.) and so on.
But, to fully benefit from this model, the application code should be written in a non-blocking manner.
That’s where having a reactive API is an ultimate weapon.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="mutiny"><a class="anchor" href="#mutiny"></a>Mutiny - A reactive programming library</h2>
<div class="sectionbody">
<div class="paragraph">
<p><a href="https://github.com/smallrye/smallrye-mutiny">Mutiny</a> is a reactive programming library allowing to express and compose asynchronous actions.
It offers 2 types:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>io.smallrye.mutiny.Uni</code> - for asynchronous action providing 0 or 1 result</p>
</li>
<li>
<p><code>io.smallrye.mutiny.Multi</code> - for multi-item (with back-pressure) streams</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Both types are lazy and follow a subscription pattern.
The computation only starts once there is an actual need for it (i.e. a subscriber enlists).</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">uni.subscribe().with(
    result -&gt; System.out.println("result is " + result),
    failure -&gt; failure.printStackTrace()
);

multi.subscribe().with(
    item -&gt; System.out.println("Got " + item),
    failure -&gt; failure.printStackTrace()
);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Both <code>Uni</code> and <code>Multi</code> expose event-driven APIs: you express what you want to do upon a given event (success, failure, etc.).
These APIs are divided into groups (types of operations) to make it more expressive and avoid having 100s of methods attached to a single class.
The main types of operations are about reacting to failure, completion, manipulating items, extracting, or collecting them.
It provides a smooth coding experience, with a navigable API, and the result does not require too much knowledge around reactive.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">httpCall
    .onFailure().recoverWithItem("my fallback");</code></pre>
</div>
</div>
<div class="paragraph">
<p>You may wonder about Reactive Streams (<a href="https://www.reactive-streams.org/" class="bare">https://www.reactive-streams.org/</a>).
<code>Multi</code> implements Reactive Streams <code>Publisher</code>, and so implements the Reactive Streams back-pressure mechanism.
<code>Uni</code> does not implement <code>Publisher</code> as the subscription to the <code>Uni</code> is enough to indicate you are interested in the result.
It is again with the idea of simpler and smoother APIs in mind as the Reactive Streams subscription/request ceremony is more complex.</p>
</div>
<div class="paragraph">
<p>Embracing the unification of reactive and imperative pillars from Quarkus, both <code>Uni</code> and <code>Multi</code> provide bridges to imperative constructs.
For example, you can transform a <code>Multi</code> into an <code>Iterable</code> or <em>await</em> the item produced by a <code>Uni</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">// Block until the result is available
String result = uni.await().indefinitely();

// Transform an asynchronous stream into a blocking iterable
stream.subscribe().asIterable().forEach(s -&gt; System.out.println("Item is " + s));</code></pre>
</div>
</div>
<div class="paragraph">
<p>At that point, if you are a RxJava or a Reactor user, you may wonder how you can use your familiar <code>Flowable</code>, <code>Single</code>, <code>Flux</code>, <code>Mono</code>&#8230;&#8203;
Mutiny allows converting <code>Unis</code> and <code>Multis</code> from and to RX Java and Reactor types:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">Maybe&lt;String&gt; maybe = uni.convert().with(UniRxConverters.toMaybe());
Flux&lt;String&gt; flux = multi.convert().with(MultiReactorConverters.toFlux());</code></pre>
</div>
</div>
<div class="paragraph">
<p>But, what about Vert.x?
Vert.x APIs are also available using Mutiny types.
The following snippet shows a usage of the Vert.x Web Client:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">// Use io.vertx.mutiny.ext.web.client.WebClient
client = WebClient.create(vertx,
                new WebClientOptions().setDefaultHost("fruityvice.com").setDefaultPort(443).setSsl(true)
                        .setTrustAll(true));
// ...
Uni&lt;JsonObject&gt; uni =
    client.get("/api/fruit/" + name)
        .send()
        .onItem().transform(resp -&gt; {
            if (resp.statusCode() == 200) {
                return resp.bodyAsJsonObject();
            } else {
                return new JsonObject()
                        .put("code", resp.statusCode())
                        .put("message", resp.bodyAsString());
            }
        });</code></pre>
</div>
</div>
<div class="paragraph">
<p>Last but not least, Mutiny has built-in integration with MicroProfile Context Propagation so you can propagate transactions, traceability data, and so on in your reactive pipeline.</p>
</div>
<div class="paragraph">
<p>But enough talking, let&#8217;s get our hands dirty!</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="bootstrapping-the-project"><a class="anchor" href="#bootstrapping-the-project"></a>Bootstrapping the project</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The easiest way to create a new Quarkus project is to open a terminal and run the following command:</p>
</div>
<div class="paragraph">
<p>For Linux and macOS users</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=getting-started-reactive \
    -DclassName="org.acme.quickstart.ReactiveGreetingResource" \
    -Dpath="/hello" \
    -Dextensions="resteasy-mutiny, resteasy-jsonb"
cd getting-started-reactive</code></pre>
</div>
</div>
<div class="paragraph">
<p>For Windows users</p>
</div>
<div class="ulist">
<ul>
<li>
<p>If using cmd, (don&#8217;t use forward slash <code>\</code>)</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create -DprojectGroupId=org.acme -DprojectArtifactId=getting-started-reactive -DclassName="org.acme.quickstart.ReactiveGreetingResource" -Dpath="/hello" -Dextensions="resteasy-mutiny,resteasy-jsonb"</code></pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>If using Powershell, wrap <code>-D</code> parameters in double quotes</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create "-DprojectGroupId=org.acme" "-DprojectArtifactId=getting-started-reactive" "-DclassName=org.acme.quickstart.ReactiveGreetingResource" "-Dpath=/hello" "-Dextensions=resteasy-mutiny,resteasy-jsonb"</code></pre>
</div>
</div>
<div class="paragraph">
<p>It generates the following in  <code>./getting-started-reactive</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the Maven structure</p>
</li>
<li>
<p>an <code>org.acme.quickstart.ReactiveGreetingResource</code> resource exposed on <code>/hello</code></p>
</li>
<li>
<p>an associated unit test</p>
</li>
<li>
<p>a landing page that is accessible on <code><a href="http://localhost:8080" class="bare">http://localhost:8080</a></code> after starting the application</p>
</li>
<li>
<p>example <code>Dockerfile</code> files for both <code>native</code> and <code>jvm</code> modes in <code>src/main/docker</code></p>
</li>
<li>
<p>the application configuration file</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The generated <code>pom.xml</code> also declares the RESTEasy Mutiny support and RESTEasy JSON-B to serialize payloads.</p>
</div>
<div class="sect2">
<h3 id="reactive-jax-rs-resources"><a class="anchor" href="#reactive-jax-rs-resources"></a>Reactive JAX-RS resources</h3>
<div class="paragraph">
<p>During the project creation, the <code>src/main/java/org/acme/quickstart/ReactiveGreetingResource.java</code> file has been created with the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quickstart;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class ReactiveGreetingResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It&#8217;s a very simple REST endpoint, returning "hello" to requests on "/hello".</p>
</div>
<div class="paragraph">
<p>Let&#8217;s now create a <code>ReactiveGreetingService</code> class with the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.getting.started;

import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;

import javax.enterprise.context.ApplicationScoped;
import java.time.Duration;

@ApplicationScoped
public class ReactiveGreetingService {

    public Uni&lt;String&gt; greeting(String name) {
        return Uni.createFrom().item(name)
                .onItem().transform(n -&gt; String.format("hello %s", name));
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then, edit the <code>ReactiveGreetingResource</code> class to match the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.getting.started;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import org.jboss.resteasy.annotations.SseElementType;
import org.jboss.resteasy.annotations.jaxrs.PathParam;
import org.reactivestreams.Publisher;

@Path("/hello")
public class ReactiveGreetingResource {

    @Inject
    ReactiveGreetingService service;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/greeting/{name}")
    public Uni&lt;String&gt; greeting(@PathParam String name) {
        return service.greeting(name);
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>ReactiveGreetingService</code> class contains a straightforward method producing a <code>Uni</code>.
While, in this example, the resulting item is emitted immediately, you can imagine any async API producing a <code>Uni</code>. We cover this later in this guide.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
In order to get Mutiny working properly with JAX-RS resources, make sure the Mutiny support for RESTEasy extension (<code>io.quarkus:quarkus-resteasy-mutiny</code>) is present, otherwise add the extension by executing the following command:
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:add-extensions \
    -Dextensions="io.quarkus:quarkus-resteasy-mutiny"</code></pre>
</div>
</div>
<div class="paragraph">
<p>Or add <code>quarkus-resteasy-mutiny</code> into your dependencies manually.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">    &lt;dependency&gt;
      &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
      &lt;artifactId&gt;quarkus-resteasy-mutiny&lt;/artifactId&gt;
    &lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now, start the application using:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">./mvnw quarkus:dev</code></pre>
</div>
</div>
<div class="paragraph">
<p>Once running, check that you get the expected greeting message by opening <a href="http://localhost:8080/hello/greeting/neo" class="bare">http://localhost:8080/hello/greeting/neo</a>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="handling-streams"><a class="anchor" href="#handling-streams"></a>Handling streams</h2>
<div class="sectionbody">
<div class="paragraph">
<p>So far, we only return an asynchronous result.
In this section, we extend the application with streams conveying multiple items.
These streams could come from Kafka or any other source of data, but to keep things simple, we just generate periodic greeting messages.</p>
</div>
<div class="paragraph">
<p>In the <code>ReactiveGreetingService</code>, add the following method:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public Multi&lt;String&gt; greetings(int count, String name) {
  return Multi.createFrom().ticks().every(Duration.ofSeconds(1))
        .onItem().transform(n -&gt; String.format("hello %s - %d", name, n))
        .transform().byTakingFirstItems(count);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It generates a greeting message every second and stops after <code>count</code> messages.</p>
</div>
<div class="paragraph">
<p>In the <code>ReactiveGreetingResource</code> add the following method:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/greeting/{count}/{name}")
public Multi&lt;String&gt; greetings(@PathParam int count, @PathParam String name) {
  return service.greetings(count, name);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This endpoint streams the items to the client as a JSON Array.
The name and number of messages are parameterized using path parameters.</p>
</div>
<div class="paragraph">
<p>So calling the endpoint produces something like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">$ curl http://localhost:8080/hello/greeting/3/neo
["hello neo - 0","hello neo - 1","hello neo - 2"]</code></pre>
</div>
</div>
<div class="paragraph">
<p>We can also generate Server-Sent Event responses by returning a <code>Multi</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
@SseElementType(MediaType.TEXT_PLAIN)
@Path("/stream/{count}/{name}")
public Multi&lt;String&gt; greetingsAsStream(@PathParam int count, @PathParam String name) {
    return service.greetings(count, name);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The only difference with the previous snippet is the produced type and the <code>@SseElementType</code> annotation indicating the type of each event.
As the <code>@Produces</code> annotation defines <code>SERVER_SENT_EVENTS</code>, JAX-RS needs it to knows the content type of each (nested) event.</p>
</div>
<div class="paragraph">
<p>You can see the result using:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">$ curl -N http://localhost:8080/hello/stream/5/neo
data: hello neo - 0

data: hello neo - 1

data: hello neo - 2

data: hello neo - 3

data: hello neo - 4</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="using-reactive-apis"><a class="anchor" href="#using-reactive-apis"></a>Using Reactive APIs</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="using-quarkus-reactive-apis"><a class="anchor" href="#using-quarkus-reactive-apis"></a>Using Quarkus reactive APIs</h3>
<div class="paragraph">
<p>Quarkus provides many reactive APIs using the Mutiny model.
In this section, we are going to see how you can use the Reactive PostgreSQL driver to interact with your database in a non-blocking and reactive way.</p>
</div>
<div class="paragraph">
<p>Create a new project using:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=getting-started-reactive-crud \
    -DclassName="org.acme.reactive.crud.FruitResource" \
    -Dpath="/fruits" \
    -Dextensions="resteasy-mutiny, resteasy-jsonb, reactive-pg-client"
cd getting-started-reactive-crud</code></pre>
</div>
</div>
<div class="paragraph">
<p>This application is interacting with a PostgreSQL database, so you need one:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">docker run --ulimit memlock=-1:-1 -it --rm=true --memory-swappiness=0 \
           --name postgres-quarkus-reactive -e POSTGRES_USER=quarkus_test \
           -e POSTGRES_PASSWORD=quarkus_test -e POSTGRES_DB=quarkus_test \
           -p 5432:5432 postgres:11.2</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then, let&#8217;s configure our datasource.
Open the <code>src/main/resources/application.properties</code> and add the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=quarkus_test
quarkus.datasource.password=quarkus_test
quarkus.datasource.reactive.url=postgresql://localhost:5432/quarkus_test
myapp.schema.create=true</code></pre>
</div>
</div>
<div class="paragraph">
<p>The 3 first lines define the datasource.
The last line is going to be used in the application to indicate whether we insert a few items when the application gets initialized.</p>
</div>
<div class="paragraph">
<p>Now, let&#8217;s create our <em>entity</em>.
Create the <code>org.acme.reactive.crud.Fruit</code> class with the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.reactive.crud;

import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import io.vertx.mutiny.pgclient.PgPool;
import io.vertx.mutiny.sqlclient.Row;
import io.vertx.mutiny.sqlclient.RowSet;
import io.vertx.mutiny.sqlclient.Tuple;

import java.util.stream.StreamSupport;

public class Fruit {

    public Long id;

    public String name;

    public Fruit() {
        // default constructor.
    }

    public Fruit(String name) {
        this.name = name;
    }

    public Fruit(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public static Multi&lt;Fruit&gt; findAll(PgPool client) {
        return client.query("SELECT id, name FROM fruits ORDER BY name ASC").execute()
                // Create a Multi from the set of rows:
                .onItem().transformToMulti(set -&gt; Multi.createFrom().items(() -&gt; StreamSupport.stream(set.spliterator(), false)))
                // For each row create a fruit instance
                .onItem().transform(Fruit::from);
    }

    public static Uni&lt;Fruit&gt; findById(PgPool client, Long id) {
        return client.preparedQuery("SELECT id, name FROM fruits WHERE id = $1").execute(Tuple.of(id))
                .onItem().transform(RowSet::iterator)
                .onItem().transform(iterator -&gt; iterator.hasNext() ? from(iterator.next()) : null);
    }

    public Uni&lt;Long&gt; save(PgPool client) {
        return client.preparedQuery("INSERT INTO fruits (name) VALUES ($1) RETURNING (id)").execute(Tuple.of(name))
                .onItem().transform(pgRowSet -&gt; pgRowSet.iterator().next().getLong("id"));
    }

    public Uni&lt;Boolean&gt; update(PgPool client) {
        return client.preparedQuery("UPDATE fruits SET name = $1 WHERE id = $2").execute(Tuple.of(name, id))
                .onItem().transform(pgRowSet -&gt; pgRowSet.rowCount() == 1);
    }

    public static Uni&lt;Boolean&gt; delete(PgPool client, Long id) {
        return client.preparedQuery("DELETE FROM fruits WHERE id = $1").execute(Tuple.of(id))
                .onItem().transform(pgRowSet -&gt; pgRowSet.rowCount() == 1);
    }

    private static Fruit from(Row row) {
        return new Fruit(row.getLong("id"), row.getString("name"));
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This <em>entity</em> contains a few fields and methods to find, update, and delete rows from the database.
These methods return either <code>Unis</code> or <code>Multis</code> as the produced items are emitted asynchronously when the results have been retrieved.
Notice that the reactive PostgreSQL client already provides <code>Uni</code> and <code>Multi</code> instances.
So you only transform the results from the database into <em>business-friendly</em> objects.</p>
</div>
<div class="paragraph">
<p>Then, let&#8217;s use this <code>Fruit</code> class in the <code>FruitResource</code>.
Edit the <code>FruitResource</code> class to match the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.reactive.crud;

import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import io.vertx.mutiny.pgclient.PgPool;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.jboss.resteasy.annotations.jaxrs.PathParam;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import java.net.URI;

@Path("fruits")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class FruitResource {

    @Inject
    @ConfigProperty(name = "myapp.schema.create", defaultValue = "true")
    boolean schemaCreate;

    @Inject
    PgPool client;

    @PostConstruct
    void config() {
        if (schemaCreate) {
            initdb();
        }
    }

    private void initdb() {
        client.query("DROP TABLE IF EXISTS fruits").execute()
                .flatMap(r -&gt; client.query("CREATE TABLE fruits (id SERIAL PRIMARY KEY, name TEXT NOT NULL)").execute())
                .flatMap(r -&gt; client.query("INSERT INTO fruits (name) VALUES ('Kiwi')").execute())
                .flatMap(r -&gt; client.query("INSERT INTO fruits (name) VALUES ('Durian')").execute())
                .flatMap(r -&gt; client.query("INSERT INTO fruits (name) VALUES ('Pomelo')").execute())
                .flatMap(r -&gt; client.query("INSERT INTO fruits (name) VALUES ('Lychee')").execute())
                .await().indefinitely();
    }

    @GET
    public Multi&lt;Fruit&gt; get() {
        return Fruit.findAll(client);
    }

    @GET
    @Path("{id}")
    public Uni&lt;Response&gt; getSingle(@PathParam Long id) {
        return Fruit.findById(client, id)
                .onItem().transform(fruit -&gt; fruit != null ? Response.ok(fruit) : Response.status(Status.NOT_FOUND))
                .onItem().transform(ResponseBuilder::build);
    }

    @POST
    public Uni&lt;Response&gt; create(Fruit fruit) {
        return fruit.save(client)
                .onItem().transform(id -&gt; URI.create("/fruits/" + id))
                .onItem().transform(uri -&gt; Response.created(uri).build());
    }

    @PUT
    @Path("{id}")
    public Uni&lt;Response&gt; update(@PathParam Long id, Fruit fruit) {
        return fruit.update(client)
                .onItem().transform(updated -&gt; updated ? Status.OK : Status.NOT_FOUND)
                .onItem().transform(status -&gt; Response.status(status).build());
    }

    @DELETE
    @Path("{id}")
    public Uni&lt;Response&gt; delete(@PathParam Long id) {
        return Fruit.delete(client, id)
                .onItem().transform(deleted -&gt; deleted ? Status.NO_CONTENT : Status.NOT_FOUND)
                .onItem().transform(status -&gt; Response.status(status).build());
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This resource returns <code>Uni</code> and <code>Multi</code> instances based on the result produced by the <code>Fruit</code> class.</p>
</div>
</div>
<div class="sect2">
<h3 id="using-vert-x-clients"><a class="anchor" href="#using-vert-x-clients"></a>Using Vert.x clients</h3>
<div class="paragraph">
<p>The previous example uses a <em>service</em> provided by Quarkus.
Also, you can use Vert.x clients directly.</p>
</div>
<div class="paragraph">
<p>First of all, make sure the <code>quarkus-vertx</code> extension is present. If not, activate the extension by executing the following command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:add-extensions \
    -Dextensions=vertx</code></pre>
</div>
</div>
<div class="paragraph">
<p>Or add <code>quarkus-vertx</code> into your dependencies manually.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
	&lt;groupId&gt;io.quarkus&lt;/groupId&gt;
	&lt;artifactId&gt;quarkus-vertx&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>There is a Mutiny version of the Vert.x APIs.
This API is divided into several artifacts you can import independently:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">groupId:artifactId</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>io.smallrye.reactive:smallrye-mutiny-vertx-core</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Mutiny API for Vert.x Core</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>io.smallrye.reactive:smallrye-mutiny-vertx-mail-client</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Mutiny API for the Vert.x Mail Client</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>io.smallrye.reactive:smallrye-mutiny-vertx-web-client</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Mutiny API for the Vert.x Web Client</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>io.smallrye.reactive:smallrye-mutiny-vertx-mongo-client</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Mutiny API for the Vert.x Mongo Client</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>io.smallrye.reactive:smallrye-mutiny-vertx-redis-client</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Mutiny API for the Vert.x Redis Client</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>io.smallrye.reactive:smallrye-mutiny-vertx-cassandra-client</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Mutiny API for the Vert.x Cassandra Client</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>io.smallrye.reactive:smallrye-mutiny-vertx-consul-client</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Mutiny API for the Vert.x Consul Client</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>io.smallrye.reactive:smallrye-mutiny-vertx-kafka-client</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Mutiny API for the Vert.x Kafka Client</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>io.smallrye.reactive:smallrye-mutiny-vertx-amqp-client</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Mutiny API for the Vert.x AMQP Client</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>io.smallrye.reactive:smallrye-mutiny-vertx-rabbitmq-client</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Mutiny API for the Vert.x RabbitMQ Client</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>You can also check the available APIs on <a href="http://smallrye.io/smallrye-reactive-utils/apidocs/" class="bare">http://smallrye.io/smallrye-reactive-utils/apidocs/</a>.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s take an example.
Add the following dependency to your application:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.smallrye.reactive&lt;/groupId&gt;
    &lt;artifactId&gt;smallrye-mutiny-vertx-web-client&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>It provides the Mutiny API of the Vert.x Web Client.
Then, you can use the web client as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.vertx;

import io.smallrye.mutiny.Uni;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.WebClientOptions;
import io.vertx.mutiny.core.Vertx;
import io.vertx.mutiny.ext.web.client.WebClient;
import org.jboss.resteasy.annotations.jaxrs.PathParam;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/fruit-data")
public class ResourceUsingWebClient {

    @Inject
    Vertx vertx;

    private WebClient client;

    @PostConstruct
    void initialize() {
        this.client = WebClient.create(vertx,
                new WebClientOptions().setDefaultHost("fruityvice.com").setDefaultPort(443).setSsl(true)
                        .setTrustAll(true));
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/{name}")
    public Uni&lt;JsonObject&gt; getFruitData(@PathParam("name") String name) {
        return client.get("/api/fruit/" + name)
                .send()
                .map(resp -&gt; {
                    if (resp.statusCode() == 200) {
                        return resp.bodyAsJsonObject();
                    } else {
                        return new JsonObject()
                                .put("code", resp.statusCode())
                                .put("message", resp.bodyAsString());
                    }
                });
    }

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>There are 2 important points:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The injected Vert.x instance has the <code>io.vertx.mutiny.core.Vertx</code> type which is the Mutiny variant of Vert.x;</p>
</li>
<li>
<p>The Web Client is created from <code>io.vertx.mutiny.ext.web.client.WebClient</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>The Mutiny version of the Vert.x APIs also offers:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>andAwait</code> methods such as <code>sendAndAwait</code>. <code>andAwait</code> indicates that the caller thread is blocked until the result is available.
Be aware not to block the event loop / IO thread that way.</p>
</li>
<li>
<p><code>andForget</code> methods such as <code>writeAndForget</code>. <code>andForget</code> is available for method returning a <code>Uni</code>.
<code>andForget</code> indicates that you don&#8217;t need the resulting <code>Uni</code> indicating the success or failure of the operation.
However, remember that if you don&#8217;t subscribe, the operation would not be triggered.
<code>andForget</code> manages this for you and manage the subscription.</p>
</li>
<li>
<p><code>toMulti</code> methods allowing to transform a Vert.x <code>ReadStream</code> into a <code>Multi</code></p>
</li>
<li>
<p><code>toBlockingIterable</code> / <code>toBlockingStream</code> methods allowing to transform a Vert.x <code>ReadStream</code> into a blocking iterable or blocking <code>java.util.Stream</code></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="using-rxjava-or-reactor-apis"><a class="anchor" href="#using-rxjava-or-reactor-apis"></a>Using RxJava or Reactor APIs</h3>
<div class="paragraph">
<p>Mutiny provides utilities to convert RxJava 2 and Project Reactor types to <code>Uni</code> and <code>Multi</code>.</p>
</div>
<div class="paragraph">
<p>RxJava 2 converters are available in the following dependency:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.smallrye.reactive&lt;/groupId&gt;
    &lt;artifactId&gt;mutiny-rxjava&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>So if you have an API returning RxJava 2 types (<code>Completable</code>, <code>Single</code>, <code>Maybe</code>, <code>Observable</code>, <code>Flowable</code>), you can create <code>Unis</code> and <code>Multis</code> as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import io.smallrye.mutiny.converters.multi.MultiRxConverters;
import io.smallrye.mutiny.converters.uni.UniRxConverters;
// ...
Uni&lt;Void&gt; uniFromCompletable = Uni.createFrom().converter(UniRxConverters.fromCompletable(), completable);
Uni&lt;String&gt; uniFromSingle = Uni.createFrom().converter(UniRxConverters.fromSingle(), single);
Uni&lt;String&gt; uniFromMaybe = Uni.createFrom().converter(UniRxConverters.fromMaybe(), maybe);
Uni&lt;String&gt; uniFromEmptyMaybe = Uni.createFrom().converter(UniRxConverters.fromMaybe(), emptyMaybe);
Uni&lt;String&gt; uniFromObservable = Uni.createFrom().converter(UniRxConverters.fromObservable(), observable);
Uni&lt;String&gt; uniFromFlowable = Uni.createFrom().converter(UniRxConverters.fromFlowable(), flowable);

Multi&lt;Void&gt; multiFromCompletable = Multi.createFrom().converter(MultiRxConverters.fromCompletable(), completable);
Multi&lt;String&gt; multiFromSingle = Multi.createFrom().converter(MultiRxConverters.fromSingle(), single);
Multi&lt;String&gt; multiFromMaybe = Multi.createFrom().converter(MultiRxConverters.fromMaybe(), maybe);
Multi&lt;String&gt; multiFromEmptyMaybe = Multi.createFrom().converter(MultiRxConverters.fromMaybe(), emptyMaybe);
Multi&lt;String&gt; multiFromObservable = Multi.createFrom().converter(MultiRxConverters.fromObservable(), observable);
Multi&lt;String&gt; multiFromFlowable = Multi.createFrom().converter(MultiRxConverters.fromFlowable(), flowable);</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also transform <code>Unis</code> and <code>Multis</code> into RxJava types:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">Completable completable = uni.convert().with(UniRxConverters.toCompletable());
Single&lt;Optional&lt;String&gt;&gt; single = uni.convert().with(UniRxConverters.toSingle());
Single&lt;String&gt; single2 = uni.convert().with(UniRxConverters.toSingle().failOnNull());
Maybe&lt;String&gt; maybe = uni.convert().with(UniRxConverters.toMaybe());
Observable&lt;String&gt; observable = uni.convert().with(UniRxConverters.toObservable());
Flowable&lt;String&gt; flowable = uni.convert().with(UniRxConverters.toFlowable());
// ...
Completable completable = multi.convert().with(MultiRxConverters.toCompletable());
Single&lt;Optional&lt;String&gt;&gt; single = multi.convert().with(MultiRxConverters.toSingle());
Single&lt;String&gt; single2 = multi.convert().with(MultiRxConverters
        .toSingle().onEmptyThrow(() -&gt; new Exception("D'oh!")));
Maybe&lt;String&gt; maybe = multi.convert().with(MultiRxConverters.toMaybe());
Observable&lt;String&gt; observable = multi.convert().with(MultiRxConverters.toObservable());
Flowable&lt;String&gt; flowable = multi.convert().with(MultiRxConverters.toFlowable());</code></pre>
</div>
</div>
<div class="paragraph">
<p>Project Reactor converters are available in the following dependency:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.smallrye.reactive&lt;/groupId&gt;
    &lt;artifactId&gt;mutiny-reactor&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>So if you have an API returning Reactor types (<code>Mono</code>, <code>Flux</code>), you can create <code>Unis</code> and <code>Multis</code> as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import io.smallrye.mutiny.converters.multi.MultiReactorConverters;
import io.smallrye.mutiny.converters.uni.UniReactorConverters;
// ...
Uni&lt;String&gt; uniFromMono = Uni.createFrom().converter(UniReactorConverters.fromMono(), mono);
Uni&lt;String&gt; uniFromFlux = Uni.createFrom().converter(UniReactorConverters.fromFlux(), flux);

Multi&lt;String&gt; multiFromMono = Multi.createFrom().converter(MultiReactorConverters.fromMono(), mono);
Multi&lt;String&gt; multiFromFlux = Multi.createFrom().converter(MultiReactorConverters.fromFlux(), flux);</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also transform <code>Unis</code> and <code>Multis</code> into Reactor types:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">Mono&lt;String&gt; mono = uni.convert().with(UniReactorConverters.toMono());
Flux&lt;String&gt; flux = uni.convert().with(UniReactorConverters.toFlux());

Mono&lt;String&gt; mono2 = multi.convert().with(MultiReactorConverters.toMono());
Flux&lt;String&gt; flux2 = multi.convert().with(MultiReactorConverters.toFlux());</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="using-completionstages-or-publisher-api"><a class="anchor" href="#using-completionstages-or-publisher-api"></a>Using CompletionStages or Publisher API</h3>
<div class="paragraph">
<p>If you are facing an API using <code>CompletionStage</code>, <code>CompletableFuture</code>, or <code>Publisher</code>, you can convert back and forth.
First, both <code>Uni</code> and <code>Multi</code> can be created from a <code>CompletionStage</code> or from a <code>Supplier&lt;CompletionStage&gt;</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">CompletableFuture&lt;String&gt; future = Uni
        // Create from a Completion Stage
        .createFrom().completionStage(CompletableFuture.supplyAsync(() -&gt; "hello"));</code></pre>
</div>
</div>
<div class="paragraph">
<p>On <code>Uni</code>, you can also produce a <code>CompletionStage</code> using <code>subscribeAsCompletionStage()</code> that produces a <code>CompletionStage</code> that would get the item or failure emitted by the <code>Uni</code>.</p>
</div>
<div class="paragraph">
<p>You can also create <code>Unis</code> and <code>Multis</code> from instances of <code>Publisher</code> using <code>createFrom().publisher(Publisher)</code>.
You can transform a <code>Uni</code> into a <code>Publisher</code> using <code>toMulti</code>.
Indeed, <code>Multi</code> implements <code>Publisher</code>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="whats-next"><a class="anchor" href="#whats-next"></a>What&#8217;s next?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This guide is an introduction to reactive in Quarkus.
There are plenty of Quarkus features that are already reactive.
The following list gives you a few examples:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="rest-json#reactive">Using Mutiny with RestEasy</a></p>
</li>
<li>
<p><a href="mailer">Sending email</a></p>
</li>
<li>
<p><a href="mongodb#reactive">Using MongoDB</a> and <a href="mongodb-panache#reactive">MongoDB with Panache</a></p>
</li>
<li>
<p><a href="reactive-sql-clients">Reactive Database Clients</a></p>
</li>
<li>
<p><a href="vertx">Using Vert.x</a></p>
</li>
<li>
<p><a href="kafka">Interacting with Kafka</a> and <a href="amqp">Interacting with AMQP</a></p>
</li>
<li>
<p><a href="neo4j#reactive">Using Neo4J</a></p>
</li>
<li>
<p><a href="reactive-routes">Using reactive routes</a></p>
</li>
</ul>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
